#!/usr/bin/perl

package GoogPl::GooGl;
our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
$VERSION = '$Revision$';

use strict;
use warnings;
use WWW::Curl::Easy;
use URI::Escape qw( uri_escape );
use URI::Title;
use Convert::Age;
use JSON qw(decode_json encode_json);
use POSIX qw(floor ceil);

require Exporter;
@ISA = qw( Exporter );
@EXPORT = qw( get_short_url );
@EXPORT_OK = qw( get_short_url );


sub register {
    my $self = shift;
    my $dbh = shift;

    my $sth = $dbh->prepare("SELECT * FROM sqlite_master WHERE type='table' AND name=?");
    $sth->bind_param(1, 'urls');
    $sth->execute;

    my $test = $sth->fetch; # rows has nothing unless you do a fetch.
    if( ! $sth->rows ) {
        $dbh->do("CREATE TABLE urls (id integer primary key autoincrement, nick varchar, channel varchar, 
                url varchar, create_date timestamp DEFAULT CURRENT_TIMESTAMP, count integer default 0, 
                last_update timestamp);");
        $dbh->do("CREATE UNIQUE INDEX channel_urls ON urls (channel, url)");
    }
}

sub process_command {
    my $self = shift;
    my ($kernel, $sender, $nickhost, $target, $msgtxt, %conf) = @_;
    my $dbh = $conf{'dbh'};

    $nickhost =~ /(.*)!(.*)@(.*)/;
    my ($nick, $ident, $host) = ($1, $2, $3);

    my $servers = $conf{'servers'};
    my $server = $$sender[0]->{'server'};
    my $admin = $servers->{$server}{'admin'};

    if( $nickhost =~ /$admin/ && $msgtxt =~ /!resetscore\s*(.*)/ ) {
        if( $1 ) {
            my $sth = $dbh->prepare("UPDATE urls SET count=0 WHERE channel=? AND nick=?");
            $sth->bind_param(1, $target);
            $sth->bind_param(2, $1);
            $sth->execute;
        }
        else {
            my $sth = $dbh->prepare("UPDATE urls SET count=0 WHERE channel=?");
            $sth->bind_param(1, $target);
            $sth->execute;
        }
    }
    elsif( $msgtxt =~ /!score\s*(.*)/ && $conf{'enable_url_log'} ) {
        if( $1 ) {
            my $sth = $dbh->prepare("SELECT SUM(count) AS score FROM urls WHERE nick=? AND channel=?");
            $sth->bind_param(1, $1);
            $sth->bind_param(2, $target);
            $sth->execute;
            my $row = $sth->fetchrow_hashref;
            $kernel->post($sender => privmsg => $target =>
                    sprintf('%s :: %d', $1, $row->{'score'}||0));
        }
        else {
            my $sth = $dbh->prepare("SELECT nick, SUM(count) AS score FROM urls WHERE channel=? GROUP BY nick ORDER BY SUM(count) DESC LIMIT 10");
            $sth->bind_param(1, $target);
            $sth->execute;
            my @nicks;
            while( my $row = $sth->fetchrow_hashref ) {
                push @nicks, sprintf('%s: %d', $row->{'nick'}, $row->{'score'});
            }
            $kernel->post($sender => privmsg => $target => 'Top Scores: '.join(', ', @nicks));
        }
        
        return 1;
    }
    elsif( $msgtxt =~ /(https?:\/\/[^\s]+)/ ) {
        my $url = $1;
        my $title = '';
        if( $conf{'enable_uri_titles'} && 
                ! grep /\Q$target\E/, @{$servers->{$server}{'no_uri_title'}} ) {
            $title = URI::Title::title($url);
        }

        if( $conf{'enable_url_log'} && $target =~ /^#/ ) {
            my $urlcheck = $url;
            $urlcheck =~ s/^(https?:\/\/)//;
            my $sth = $dbh->prepare("SELECT *, strftime('\%s', 'now') - strftime('\%s', create_date) AS age FROM urls WHERE channel=? AND url like ?");
            $sth->bind_param(1, $target);
            $sth->bind_param(2, '%//'.$urlcheck);
            $sth->execute;

            my $row = $sth->fetchrow_hashref;
            if( $sth->rows && $row->{'nick'} ne $nick ) {
                # ignoring any timestamp or irc client formatting, look to see
                # if poster is giving credit to original poster, ie -
                # 03:59 <+netmunky> http://www.google.com/search?q=googpl
                my $orignick = $row->{'nick'};
                if( $msgtxt !~ /^[^a-b]*\Q$orignick\E[ ]*>/ ) {
                    $title = sprintf('OLD: Originally posted by %s %s ago'.($title ? ' // %s' : ''),
                        $row->{'nick'}, Convert::Age::encode($row->{'age'}), $title);
                    $sth->finish;
                    $sth = $dbh->prepare("UPDATE urls SET count=count+1, last_update=CURRENT_TIMESTAMP WHERE id=?");
                    $sth->bind_param(1, $row->{'id'});
                    $sth->execute;
                }
            }
            elsif( ! $sth->rows ) {
                $sth->finish;
                $sth = $dbh->prepare("INSERT INTO urls (nick, channel, url) VALUES (?,?,?)");
                $sth->bind_param(1, $nick);
                $sth->bind_param(2, $target);
                $sth->bind_param(3, $url);
                $sth->execute;
            }
            $sth->finish;
        }

        if( $url =~ /https?:\/\/(?:www.)?youtube.+watch\?(?:.*&)?v=([^&#]+)(?:[^#]*)(#t=[\d]+m[\d]+s)?/ ) {
            $url = "http://youtu.be/$1$2";
            $kernel->post($sender => privmsg => $target => "$url $title");
        }
        elsif( length($url) > $conf{'min_length'} || $target !~ /^[#&]/ ) {
            my $shortUrl = get_short_url($url, %conf) || '';
            $kernel->post($sender => privmsg => $target => "$shortUrl $title");
        }
        elsif( $title ) {
            $kernel->post($sender => privmsg => $target => $title);
        }

        return 1;
    }

    return 0;
}

sub get_short_url {
    my $url = shift;
    my %conf = @_;
    return undef if ! $url;

    my $curl = WWW::Curl::Easy->new;

    my %post = ('longUrl'=>$url);
    if ($conf{'googl_api_key'}) {
        $post{'key'} = $conf{'googl_api_key'};
    }
    my $json = encode_json(\%post);
    my $apiUrl = 'https://www.googleapis.com/urlshortener/v1/url';
    if ($conf{'googl_api_key'}) {
        $apiUrl .= "?key=".$conf{'googl_api_key'};
    }
    $curl->setopt(CURLOPT_URL, $apiUrl);
    $curl->setopt(CURLOPT_POST, 1);
    $curl->setopt(CURLOPT_REFERER, $conf{'referer'});
    $curl->setopt(CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
    $curl->setopt(CURLOPT_POSTFIELDS, $json);
    my $response_body;
    open (my $fileb, ">", \$response_body);
    $curl->setopt(CURLOPT_WRITEDATA, $fileb);

    my $retcode = $curl->perform;

    if($retcode==0){
        my $json = decode_json($response_body);
        if( $json->{'error'} ) {
            warn "An error occured: ".$json->{'error'}{'message'}."\n";
            return undef;
        }
        return $json->{'id'};
    }
    else {
        return "An error occured: ".$curl->strerror($retcode)." ($retcode)\n";
        return undef;
    }
}

1;
